package com.jxb.netty.network.byteBuffer;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.CompositeByteBuf;
import io.netty.util.CharsetUtil;
import io.netty.util.internal.ObjectUtil;

public class NettyTest {

    public static void main(String[] args) {
        //创建ByteBuf
        ByteBuf byteBuf = createByteBuf();
        //写入字节
        writeBytes(byteBuf);
        //读取数据
        readBytes(byteBuf);
        //标记回退
//        byteBuf.resetReaderIndex();
//        System.out.println(byteBuf);
        //对ByteBuf进行切片,切片的位置是读和写索引之间的内容

        //内存拷贝
        // 共享相同的底层数据，拥有独立的读写索引和标记
//        ByteBuf slice = byteBuf.slice();
//        //修改索引为0的数据
//        slice.setByte(0,(byte)9);
//        byte[] bytes = new byte[]{0};
//        byteBuf.getBytes(1,bytes);
//        System.out.println("slice" + slice);
//        System.out.println("byteBuf" + bytes[0]);
        //通过duplicate进行拷贝，这种拷贝不共享内存
//        ByteBuf duplicate = byteBuf.duplicate();
//        //修改原始的ByteBuf??
//        byteBuf.setByte(0,(byte)6);
//        byte[] bytes1 = new byte[]{0};
//        duplicate.readBytes(bytes1);
//        byte[] bytes2 = new byte[]{0};
//        byteBuf.readBytes(bytes2);
//        System.out.println("duplicate------>"+bytes1[0]);
//        System.out.println("byteBuf------>"+bytes2[0]);

        //CompositeByteBuf
        //用于管理多个ByteBuf
        //内部维护了一个Component数组，每个Component维护一个ByteBuf
//        ByteBuf buf1 = ByteBufAllocator.DEFAULT.buffer(5);
//        buf1.writeBytes(new byte[]{1, 2, 3, 4, 5});
//        ByteBuf buf2 = ByteBufAllocator.DEFAULT.buffer(5);
//        buf2.writeBytes(new byte[]{6, 7, 8, 9, 10});
//        CompositeByteBuf buf3 = ByteBufAllocator.DEFAULT.compositeBuffer();
//        buf3.addComponents(true,buf1,buf2);
//        System.out.println("buf3---------->"+buf3);

        //retain & release
        //netty用引用计数法来控制内存
        //ByteBuf初始化计数为0
        //retain计数减一
        //release计数加一
        //当计数为0时，ByteBuf不能再用，已经被回收
        ByteBuf byteBuf1 = ByteBufAllocator.DEFAULT.heapBuffer();
        byteBuf1.retain();
        byteBuf1.release();
        byteBuf1.setByte(1,(byte)2);

        //扩容
//        int i = calculateNewCapacity(16*1048576, 16*1048576);
//        System.out.println(i);
    }

    private static void readBytes(ByteBuf byteBuf) {
        //读取一个字节
        byte b = byteBuf.readByte();
        System.out.println(byteBuf);
    }

    private static void writeBytes(ByteBuf byteBuf) {
        byteBuf.writeBytes(new byte[]{1,2,3,4});
        System.out.println(byteBuf);
    }

    private static ByteBuf createByteBuf() {
        //堆内存
//        ByteBuf byteBuf = ByteBufAllocator.DEFAULT.heapBuffer();
        //直接内存
//        ByteBuf directBuffer = ByteBufAllocator.DEFAULT.directBuffer();
        ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer(10);
//        System.out.println(byteBuf);
        System.out.println(buffer);
        return buffer;
    }


    public static int calculateNewCapacity(int minNewCapacity, int maxCapacity) {
        ObjectUtil.checkPositiveOrZero(minNewCapacity, "minNewCapacity");
        if (minNewCapacity > maxCapacity) {
            throw new IllegalArgumentException(String.format("minNewCapacity: %d (expected: not greater than maxCapacity(%d)", minNewCapacity, maxCapacity));
        } else {
            int threshold = 4194304;
            if (minNewCapacity == 4194304) {
                return 4194304;
            } else {
                int newCapacity;
                //判断新容量是否大于4M
                if (minNewCapacity > 4194304) {
                    //计算有多少个阈值，然后再乘以4194304
                    newCapacity = minNewCapacity / 4194304 * 4194304;
                    //如果所需的新容量 大于 最大容量减去一个4m阈值
                    if (newCapacity > maxCapacity - 4194304) {
                        //将最大阈值赋值给新容量
                        newCapacity = maxCapacity;
                    } else {
                        //新容量 小于 最大容量减去一个4m阈值
                        //就进行4M累加
                        newCapacity += 4194304;
                    }

                    return newCapacity;
                } else {
                    //所需容量小于4m，容量就会指数性增长
                    for(newCapacity = 64; newCapacity < minNewCapacity; newCapacity <<= 1) {
                    }

                    return Math.min(newCapacity, maxCapacity);
                }
            }
        }
    }


}
